import serial
import serial.tools.list_ports
from PyQt6 import QtCore, QtGui
from PyQt6.QtGui import QIcon
from PyQt6.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QGridLayout
from qfluentwidgets import (
    BodyLabel, ComboBox, CheckBox, LineEdit,
    PrimaryPushButton, PushButton, TextEdit,
    VerticalSeparator, CaptionLabel, StrongBodyLabel, MessageBox
)
from qfluentwidgets.common.animation import BackgroundAnimationWidget
from qfluentwidgets.components.widgets.frameless_window import FramelessWindow
from qfluentwidgets.window.fluent_window import FluentTitleBar

from config import IMG_PATH
from util import SerialThread
from ui.qss import LogEdit_style


class mainWindow(BackgroundAnimationWidget, FramelessWindow):
    def __init__(self, parent=None):
        super().__init__(parent=parent)
        self.setUp_ui()

    def setUp_ui(self):
        self.main_layout = QVBoxLayout()
        self.main_layout.setContentsMargins(0, 50, 0, 0)
        self.setLayout(self.main_layout)

        icon = QIcon(str(IMG_PATH / 'sscom.svg'))  # 再创建图标

        self.setWindowIcon(icon)

        title_bar = FluentTitleBar(self)
        title_bar.iconLabel.setFixedSize(24, 24)
        title_bar.iconLabel.setPixmap(QIcon(icon).pixmap(24, 24))
        title_bar.hBoxLayout.setContentsMargins(18, 0, 0, 0)
        self.setTitleBar(title_bar)

        # 修复：确保标题栏在最上层
        self.titleBar.raise_()

        # 修复：移除 setCentralWidget 调用，直接使用 FluentWindowBase 的默认布局
        self.centralWidget = QWidget(self)

        self.widgetLayout = QVBoxLayout(self.centralWidget)  # 使用 QVBoxLayout 作为主布局
        self.centralWidget.setLayout(self.widgetLayout)  # 设置中央控件的布局

        self.main_layout.addWidget(self.centralWidget)

        self.setup_sub_layout()
        self.setup_button()
        self.setup_h_layout()

        # 状态栏
        self.statusBar = MessageBox("状态提示", "就绪", self)
        self.statusBar.hide()  # 如果不想用 QMessageBox，也可以自定义 QLabel + setStatusBar

        self.retranslateUi()
        QtCore.QMetaObject.connectSlotsByName(self)

    def setup_sub_layout(self):
        # 主布局
        self.sub_layout = QVBoxLayout()
        self.widgetLayout.addLayout(self.sub_layout)  # 将主布局添加到中央控件的布局中

        # 接收区文本浏览器（使用 TextEdit 模拟）
        self.receive_textBrowser = TextEdit()
        self.receive_textBrowser.setPlaceholderText("接收数据显示在此处...")
        self.receive_textBrowser.setStyleSheet(LogEdit_style)
        font = QtGui.QFont()
        font.setFamily("Ubuntu Mono")
        self.receive_textBrowser.setFont(font)
        self.sub_layout.addWidget(self.receive_textBrowser)

    def setup_button(self):
        # 底部按钮区域
        button_layout = QHBoxLayout()

        buttons = [
            ("打开文件", "openfile_pushButton"),
            ("发送文件", "sendfile_pushButton"),
            ("停止", "stop_pushButton"),
            ("保存窗口", "save_pushButton"),
            ("清除窗口", "clear_pushButton"),
            ("帮助", "help_pushButton"),
            ("—", "dash_pushButton"),
            ("扩展", "ext_pushButton"),
        ]

        self.button_widgets = {}
        for text, name in buttons:
            if text == "—" or text == "扩展":
                btn = PushButton(text)
            elif text == "帮助":
                btn = PushButton("帮助文档")
            else:
                btn = PrimaryPushButton(text)
            setattr(self, name, btn)
            button_layout.addWidget(btn)

        self.sub_layout.addLayout(button_layout)

    def setup_h_layout(self):
        # 左右分栏布局
        h_layout = QHBoxLayout()
        self.sub_layout.addLayout(h_layout)

        # 左侧面板 - 串口参数区域
        left_panel = QWidget()
        left_layout = QVBoxLayout(left_panel)

        labels = ["串口号", "波特率", "数据位", "停止位", "校验位", "流  控"]
        self.comboboxes = []  # 初始化列表
        for label_text in labels:
            layout, combobox = self.create_label_combobox(label_text)  # 修改：接收 combobox
            left_layout.addLayout(layout)
            self.comboboxes.append(combobox)  # 新增：将 combobox 添加到列表中
        left_layout.addStretch()
        h_layout.addWidget(left_panel, stretch=1)

        # 垂直分割线
        h_layout.addWidget(VerticalSeparator())

        # 右侧面板 - 操作区域
        right_panel = QWidget()
        self.gridLayout = QGridLayout(right_panel)

        # 控件定义
        self.openserial_pushButton = PrimaryPushButton("打开串口")
        self.hexsend_checkBox = CheckBox("HEX发送")
        self.rts_checkBox = CheckBox("RTS")
        self.label_8 = BodyLabel("ms/次")
        self.sendLineEdit = LineEdit()
        self.sendLineEdit.setPlaceholderText("请输入要发送的数据...")
        self.hexdisplay_checkBox = CheckBox("HEX显示")
        self.dtr_checkBox = CheckBox("DTR")
        self.timer_lineEdit = LineEdit()
        self.timer_lineEdit.setText("1000")
        self.led_label = CaptionLabel("● 状态指示灯")
        self.send_pushButton = PrimaryPushButton("发送")
        self.newLineCheckBox = CheckBox("发送新行")
        self.textBrowser = TextEdit()
        self.timersend_checkBox = CheckBox("定时发送")
        self.label_9 = StrongBodyLabel("字符串输入框:")
        self.label_7 = StrongBodyLabel("SSCOM")

        # 布局添加控件
        self.gridLayout.addWidget(self.openserial_pushButton, 0, 0, 1, 2)
        self.gridLayout.addWidget(self.hexsend_checkBox, 1, 5, 1, 2)
        self.gridLayout.addWidget(self.rts_checkBox, 2, 1, 1, 3)
        self.gridLayout.addWidget(self.label_8, 3, 6, 1, 1)
        self.gridLayout.addWidget(self.sendLineEdit, 5, 0, 1, 9)
        self.gridLayout.addWidget(self.hexdisplay_checkBox, 0, 5, 1, 2)
        self.gridLayout.addWidget(self.dtr_checkBox, 2, 0, 1, 1)
        self.gridLayout.addWidget(self.timer_lineEdit, 3, 3, 1, 3)
        self.gridLayout.addWidget(self.led_label, 0, 2, 1, 2)
        self.gridLayout.addWidget(self.send_pushButton, 4, 4, 1, 2)
        self.gridLayout.addWidget(self.newLineCheckBox, 2, 5, 1, 2)
        self.gridLayout.addWidget(self.textBrowser, 0, 7, 5, 1)
        self.gridLayout.addWidget(self.timersend_checkBox, 3, 0, 1, 3)
        self.gridLayout.addWidget(self.label_9, 4, 0, 1, 3)
        self.gridLayout.addWidget(self.label_7, 1, 0, 1, 5)

        h_layout.addWidget(right_panel, stretch=3)

    def create_label_combobox(self, label_text):
        layout = QHBoxLayout()
        label = BodyLabel(label_text)
        combobox = ComboBox()
        combobox.setFixedWidth(120)
        layout.addWidget(label)
        layout.addWidget(combobox)
        return layout, combobox # 修改：同时返回 layout 和 combobox

    def set_common_font(self, widget):
        font = QtGui.QFont()
        font.setPointSize(10)
        widget.setFont(font)

    def retranslateUi(self):
        _translate = QtCore.QCoreApplication.translate
        self.setWindowTitle(_translate("MainWindow", "SSCOM Fluent Design Version"))


class SScomApp(mainWindow):
    def __init__(self):
        super().__init__()
        self.serial = serial.Serial()
        self.serial_thread = None
        self.openserial_pushButton.clicked.connect(self.toggle_serial)
        self.send_pushButton.clicked.connect(self.send_data)
        # 由于 clear_pushButton 属性未知，需要先确认该按钮是否正确创建
        # 假设 clear_pushButton 是在 setup_button 方法中创建的，可通过 getattr 安全获取属性
        try:
            clear_button = getattr(self, 'clear_pushButton')
            clear_button.clicked.connect(self.receive_textBrowser.clear)
        except AttributeError:
            print("未找到 clear_pushButton 属性，请检查按钮是否正确创建。")
            # 以下状态设置可以保留，如果 clear_pushButton 对初始状态有影响
            # self.statusBar.setVisible(True)
            # self.led_label.setText("● 关闭")
            # self.update_serial_ports() # 从此处移除

        self.update_serial_ports() # 修改：确保 update_serial_ports 总是在 UI 初始化后被调用

    def update_serial_ports(self):
        ports = serial.tools.list_ports.comports()
        self.comboboxes[0].clear()
        for port in ports:
            self.comboboxes[0].addItem(port.device)
        self.comboboxes[1].addItems(["9600", "115200", "57600"])
        self.comboboxes[2].addItems(["5", "6", "7", "8"])
        self.comboboxes[3].addItems(["1", "1.5", "2"])
        self.comboboxes[4].addItems(["None", "Even", "Odd", "Mark", "Space"])
        self.comboboxes[5].addItems(["None", "XON/XOFF", "RTS/CTS", "DSR/DTR"])

    def toggle_serial(self):
        if self.serial.is_open:
            self.serial.close()
            if self.serial_thread:
                self.serial_thread.stop()
            self.openserial_pushButton.setText("打开串口")
            self.led_label.setText("● 关闭")
            self.statusBar.setText("串口已关闭")
        else:
            try:
                self.serial.port = self.comboboxes[0].currentText()
                self.serial.baudrate = int(self.comboboxes[1].currentText())
                self.serial.bytesize = int(self.comboboxes[2].currentText())
                self.serial.stopbits = float(self.comboboxes[3].currentText())
                parity = self.comboboxes[4].currentText()
                self.serial.parity = getattr(serial, f"PARITY_{parity.upper()}", serial.PARITY_NONE)
                flow = self.comboboxes[5].currentText().upper()
                self.serial.xonxoff = (flow == "XON/XOFF")
                self.serial.rtscts = (flow == "RTS/CTS")
                self.serial.dsrdtr = (flow == "DSR/DTR")
                self.serial.open()
                self.serial_thread = SerialThread(self.serial)
                self.serial_thread.data_received.connect(self.on_data_received)
                self.serial_thread.start()
                self.openserial_pushButton.setText("关闭串口")
                self.led_label.setText("● 已连接")
                box = MessageBox("串口已打开", "", self)
                box.show()
            except Exception as e:
                self.statusBar.setText(f"打开串口失败: {e}")

    def on_data_received(self, data):
        if self.hexdisplay_checkBox.isChecked():
            hex_str = " ".join(f"{b:02X}" for b in data)
            self.receive_textBrowser.append(hex_str)
        else:
            self.receive_textBrowser.append(data.decode(errors="ignore"))

    def send_data(self):
        if not self.serial.is_open:
            box = MessageBox("请先打开串口", "", self)
            box.show()
            return

        data = self.sendLineEdit.text()
        if self.hexsend_checkBox.isChecked():
            try:
                bytes_to_send = bytes.fromhex(data)
            except ValueError:
                box = MessageBox("HEX格式错误", "", self)
                box.show()
                return
        else:
            bytes_to_send = data.encode()

        if self.newLineCheckBox.isChecked():
            bytes_to_send += b"\r\n"

        try:
            self.serial.write(bytes_to_send)
            box = MessageBox("发送成功", "", self)
            box.show()
        except Exception as e:
            box = MessageBox("发送失败", str(e), self)
            box.show()
